package com.board.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.board.dao.AccountRoleMapper;
import com.board.dao.ResourceMapper;
import com.board.dao.RoleMapper;
import com.board.dao.RoleResourceMapper;
import com.board.dto.ResourceDto;
import com.board.dto.RoleDto;
import com.board.entity.AccountRole;
import com.board.entity.Resource;
import com.board.entity.Role;
import com.board.entity.RoleResource;
import com.board.exception.RoleResourceException;
import com.board.param.ResourceRoleUpdateParam;
import com.board.service.RoleResourceService;
import com.board.util.JwtUtil;
import com.board.util.PageInfo;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author 小叶
 * @since 2024年04月03日
 */
@Service
public class RoleResourceServiceImpl extends ServiceImpl<RoleResourceMapper, RoleResource> implements RoleResourceService {
    @Autowired
    private RoleResourceMapper roleResourceMapper;
    @Autowired
    private RoleMapper roleMapper;
    @Autowired
    private ResourceMapper resourceMapper;
    @Autowired
    private AccountRoleMapper accountRoleMapper;
    @Override
    public PageInfo<RoleDto> roleResource(int pageNum, int pageSize) {
        ArrayList<RoleDto> dtos = new ArrayList<>();//要添加到pageInfo里面的dto集合
        //先根据分页查询出对应页数的角色
        Page<Role> page = new Page<Role>(pageNum,pageSize);
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.orderByAsc("id");
        roleMapper.selectPage(page,wrapper);
        List<Role> roles = page.getRecords();//查询出来的所有角色
        for (Role role : roles) {
            //查询出该角色对应的所有资源id
            QueryWrapper<RoleResource> queryWrapper = new QueryWrapper<>();
            queryWrapper.eq("role_id",role.getRoleId());
            List<RoleResource> roleResources = roleResourceMapper.selectList(queryWrapper);
            ArrayList<Integer> list = new ArrayList<>();
            for (RoleResource roleResource : roleResources) {
                list.add(roleResource.getResoruceId());
            }
            RoleDto roleDto = new RoleDto();
            roleDto.setResourceIds(list);
            roleDto.setId(role.getRoleId());
            roleDto.setRoleName(role.getRoleName());
            dtos.add(roleDto);
        }
        PageInfo pageInfo = BeanUtil.toBean(page, PageInfo.class);
        pageInfo.setList(dtos);
        pageInfo.setPages(page.getPages());
        return pageInfo;
    }

    @Override
    public RoleDto updateRoleResource(ResourceRoleUpdateParam param) {
        //修改角色资源
        //先判断角色id以及对应的资源id是否都存在，
        Role role = roleMapper.selectById(param.getRoleId());
        if(role==null) throw new RoleResourceException(500,"角色不存在");

        List<Resource> resources = resourceMapper.selectBatchIds(param.getResourceIds());
        if(param.getResourceIds().size()!=resources.size()){
            throw new RoleResourceException(500,"角色的资源有不存在的");
        }
        //传递进来的资源id不能重复
        Set<Integer> set = new HashSet<>(param.getResourceIds());
        if(set.size()!=param.getResourceIds().size()){
            throw new RoleResourceException(500,"修改的资源中有重复的");
        }
        // 然后还要判断传递进来的非一级菜单都要有对应的父id，不能单独存在(通过判断父id是否存在于集合中就行，不用判断一级菜单)
        for (Resource resource : resources) {
            if(resource.getParentId()!=0){
                //不是一级菜单，需要判断父菜单id是否存在
                if(!param.getResourceIds().contains(resource.getParentId())){
                    throw new RoleResourceException(500,"非一级菜单不能单独存在");
                }
            }
        }
        //可以修改:先删除role_resource表中该角色原来的所有资源，再新增修改后的资源
        QueryWrapper<RoleResource> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("role_id",param.getRoleId());
        roleResourceMapper.delete(queryWrapper);

        for (Integer resourceId : param.getResourceIds()) {
            RoleResource roleResource = new RoleResource();
            roleResource.setRoleId(param.getRoleId());
            roleResource.setResoruceId(resourceId);
            roleResourceMapper.insert(roleResource);
        }
        RoleDto dto = new RoleDto();
        dto.setRoleName(role.getRoleName());
        dto.setResourceIds(param.getResourceIds());
        return dto;
    }

    @Override
    public List<Resource> findResourceByLevel(Integer level) {
        if(level!=1 && level!=2 && level!=3) throw new RoleResourceException(500,"级别错误");
        //因为是找父菜单，所以查询条件是传递的级别-1
        QueryWrapper<Resource> wrapper = new QueryWrapper<>();
        wrapper.eq("level",level-1);
        List<Resource> list = resourceMapper.selectList(wrapper);
        return list;
    }

    @Override
    public List<ResourceDto> findMenu(String token) {
        //先根据账号id查询出来所有的菜单资源，包括一级二级和接口地址
        Integer accountId = (Integer) JwtUtil.getData(token, "id");
        List<Resource> menus= resourceMapper.findMenu(accountId);
        //先找出所有的一级菜单
        List<ResourceDto> resources=new ArrayList<>();
        for (Resource resource : menus) {
            if(resource.getLevel()==1){
                ResourceDto resourceDto = BeanUtil.toBean(resource, ResourceDto.class);
                resources.add(resourceDto);
            }
        }
        //找出一级菜单下的所有二级菜单
        for (ResourceDto first : resources) {
            List<ResourceDto> second=new ArrayList<>();//一级菜单下的二级菜单集合
            for (Resource resource : menus) {
                if(resource.getParentId()==first.getId()){
                    ResourceDto resourceDto = BeanUtil.toBean(resource, ResourceDto.class);
                    second.add(resourceDto);
                }
            }
            first.setChildren(second);//遍历完所有resource之后，将二级菜单添加到一级菜单下
        }
        return resources;
    }

    @Override
    public List<Resource> findButton(String resourceUrl, Integer accountId) {
        QueryWrapper<AccountRole> queryWrapper2 = new QueryWrapper<>();
        queryWrapper2.eq("account_id",accountId);
        AccountRole accountRole = accountRoleMapper.selectOne(queryWrapper2);
        System.out.println(accountRole);
        //查询出该角色拥有的所有资源id
        QueryWrapper<RoleResource> queryWrapper3 = new QueryWrapper<>();
        System.out.println(accountRole.getRoleId());
        queryWrapper3.eq("role_id",accountRole.getRoleId());
        List<RoleResource> resources = roleResourceMapper.selectList(queryWrapper3);
        ArrayList<Integer> ids = new ArrayList<>();
        for (RoleResource roleResource : resources) {
            ids.add(roleResource.getResoruceId());
        }
        //筛选出资源id的级别为3的
        QueryWrapper<Resource> wrapper = new QueryWrapper<>();
        wrapper.eq("level",3);
        wrapper.in("id",ids);
        List<Resource> list1 = resourceMapper.selectList(wrapper);
        return list1;

    }
}
